package com.sites.cms.permission;

import javax.servlet.http.HttpSession;

import com.jfinal.aop.Aop;
import com.jfinal.template.Directive;
import com.jfinal.template.Env;
import com.jfinal.template.TemplateException;
import com.jfinal.template.expr.ast.Expr;
import com.jfinal.template.expr.ast.ExprList;
import com.jfinal.template.io.Writer;
import com.jfinal.template.stat.ParseException;
import com.jfinal.template.stat.Scope;
import com.sites.common.SiteInfo;
import com.sites.common.model.Account;

/**
 * 单个菜单或按钮的控制，需要指定具体的actionKey
 * 
 * 用法示例：
 * #ped("actionKey")
 * 		<a>按钮或者菜单</a>
 * #end
 * 
 * @author zyg
 * 2020年1月30日 下午4:43:41
 */
public class PermissionElementDirective extends Directive {

	private Expr valueExpr;
	private int paraNum;
	
	private PermissionService permSrv = Aop.get(PermissionService.class);
	
	/**
	 * 指令被解析时注入指令参数表达式列表，继承类可以通过覆盖此方法对参数长度和参数类型进行校验
	 */
	@Override
	public void setExprList(ExprList exprList) {
		paraNum = exprList.length();
		if(paraNum != 1){
			throw new ParseException("Wrong number parameter of #ped directive, one parameters are allowed here only", location);
		}
		valueExpr = exprList.getExpr(0);
	}
	
	@Override
	public void exec(Env env, Scope scope, Writer writer) {
		Object valueObject = valueExpr.eval(scope);
		if(valueObject instanceof String){
			String valueString = valueObject.toString();
			HttpSession session = (HttpSession) scope.get("session");
			if(session != null){
				Account account = (Account) session.getAttribute(SiteInfo.account);
				boolean flag = hasElementPerm(valueString, account);
				if(flag){
					stat.exec(env, scope, writer);
				}				
			}
		} else {
			throw new TemplateException("The parameter string of #ped directive must be String type", location);
		}
	}
	
	private boolean hasElementPerm(String actionKey, Account account){
		boolean flag = false;
		if(account != null){
			if(SiteInfo.adminName.equals(account.getUserName())){
				flag = true;
			}
			if(!flag){
				flag = permSrv.hasElementPerm(actionKey, account.getId());
			}
		}
		return flag;
	}
	
	/**
	 * 指令具有结束标签
	 */
	@Override
	public boolean hasEnd() {
		return true;
	}

}
